OPENSSL_DIR := /usr
OBJECTS := src/cert.o \
+ src/cmd_opt.o \
src/ext.o \
src/key.o \
src/main.o \
struct cert_s {
int id; /* Unique identifier */
+ const char *opt; /* Command line option to pass filename */
const char *fn; /* Filename to save the certificate */
const char *cn; /* Subject CN (Company Name) */
};
/* Exported API */
+int cert_init(void);
+cert_t *cert_get_by_opt(const char *opt);
int cert_add_ext(X509 *issuer, X509 *subject, int nid, char *value);
int cert_new(cert_t *cert, int days, int ca, STACK_OF(X509_EXTENSION) * sk);
--- /dev/null
+/*
+ * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CMD_OPT_H_
+#define CMD_OPT_H_
+
+#include <getopt.h>
+
+#define CMD_OPT_MAX_NUM 64
+
+/* Supported long command line option types */
+enum {
+ CMD_OPT_CERT,
+ CMD_OPT_KEY,
+ CMD_OPT_EXT
+};
+
+/* Exported API*/
+int cmd_opt_add(const char *name, int has_arg, int val);
+const struct option *cmd_opt_get_array(void);
+const char *cmd_opt_get_name(int idx);
+
+#endif /* CMD_OPT_H_ */
* - V_ASN1_OCTET_STRING
*/
int type;
+ const char *opt; /* Command line option to specify data */
/* Extension data (depends on extension type) */
union {
const char *fn; /* File with extension data */
};
/* Exported API */
-int ext_register(ext_t *tbb_ext);
+int ext_init(void);
+ext_t *ext_get_by_opt(const char *opt);
X509_EXTENSION *ext_new_hash(int nid, int crit, const EVP_MD *md,
unsigned char *buf, size_t len);
X509_EXTENSION *ext_new_nvcounter(int nid, int crit, int value);
*/
typedef struct key_s {
int id; /* Key id */
+ const char *opt; /* Command line option to specify a key */
const char *desc; /* Key description (debug purposes) */
char *fn; /* Filename to load/store the key */
EVP_PKEY *key; /* Key container */
} key_t;
/* Exported API */
+int key_init(void);
+key_t *key_get_by_opt(const char *opt);
int key_create(key_t *key, int type);
int key_load(key_t *key, unsigned int *err_code);
int key_store(key_t *key);
#include <openssl/x509v3.h>
#include "cert.h"
+#include "cmd_opt.h"
#include "debug.h"
#include "key.h"
#include "platform_oid.h"
cert->x = x;
return 1;
}
+
+int cert_init(void)
+{
+ cert_t *cert;
+ int rc = 0;
+ unsigned int i;
+
+ for (i = 0; i < num_certs; i++) {
+ cert = &certs[i];
+ rc = cmd_opt_add(cert->opt, required_argument, CMD_OPT_CERT);
+ if (rc != 0) {
+ break;
+ }
+ }
+
+ return rc;
+}
+
+cert_t *cert_get_by_opt(const char *opt)
+{
+ cert_t *cert = NULL;
+ unsigned int i;
+
+ for (i = 0; i < num_certs; i++) {
+ cert = &certs[i];
+ if (0 == strcmp(cert->opt, opt)) {
+ return cert;
+ }
+ }
+
+ return NULL;
+}
--- /dev/null
+/*
+ * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <getopt.h>
+#include <stddef.h>
+#include <cmd_opt.h>
+
+/* Command line options */
+static struct option long_opt[CMD_OPT_MAX_NUM+1];
+static int num_reg_opt;
+
+int cmd_opt_add(const char *name, int has_arg, int val)
+{
+ if (num_reg_opt >= CMD_OPT_MAX_NUM) {
+ return -1;
+ }
+ long_opt[num_reg_opt].name = name;
+ long_opt[num_reg_opt].has_arg = has_arg;
+ long_opt[num_reg_opt].flag = 0;
+ long_opt[num_reg_opt].val = val;
+ num_reg_opt++;
+
+ return 0;
+}
+
+const struct option *cmd_opt_get_array(void)
+{
+ return long_opt;
+}
+
+const char *cmd_opt_get_name(int idx)
+{
+ if (idx >= num_reg_opt) {
+ return NULL;
+ }
+
+ return long_opt[idx].name;
+}
#include <openssl/asn1t.h>
#include <openssl/err.h>
#include <openssl/x509v3.h>
+
+#include "cmd_opt.h"
#include "ext.h"
DECLARE_ASN1_ITEM(ASN1_INTEGER)
*
* Return: 0 = success, Otherwise: error
*/
-int ext_register(ext_t *exts)
+int ext_init(void)
{
ext_t *ext;
X509V3_EXT_METHOD *m;
- int i = 0, nid, ret;
+ int nid, ret;
+ unsigned int i;
- while ((ext = &exts[i++]) && ext->oid) {
+ for (i = 0; i < num_extensions; i++) {
+ ext = &extensions[i];
+ /* Register command line option */
+ if (ext->opt) {
+ if (cmd_opt_add(ext->opt, required_argument,
+ CMD_OPT_EXT)) {
+ return 1;
+ }
+ }
+ /* Register the extension OID in OpenSSL */
+ if (ext->oid == NULL) {
+ continue;
+ }
nid = OBJ_create(ext->oid, ext->sn, ext->ln);
if (ext->alias) {
X509V3_EXT_add_alias(nid, ext->alias);
return ex;
}
+
+ext_t *ext_get_by_opt(const char *opt)
+{
+ ext_t *ext = NULL;
+ unsigned int i;
+
+ /* Sequential search. This is not a performance concern since the number
+ * of extensions is bounded and the code runs on a host machine */
+ for (i = 0; i < num_extensions; i++) {
+ ext = &extensions[i];
+ if (ext->opt && !strcmp(ext->opt, opt)) {
+ return ext;
+ }
+ }
+
+ return NULL;
+}
#include <openssl/pem.h>
#include "cert.h"
+#include "cmd_opt.h"
#include "debug.h"
#include "key.h"
#include "platform_oid.h"
return 0;
}
+
+int key_init(void)
+{
+ key_t *key;
+ int rc = 0;
+ unsigned int i;
+
+ for (i = 0; i < num_keys; i++) {
+ key = &keys[i];
+ if (key->opt != NULL) {
+ rc = cmd_opt_add(key->opt, required_argument,
+ CMD_OPT_KEY);
+ if (rc != 0) {
+ break;
+ }
+ }
+ }
+
+ return rc;
+}
+
+key_t *key_get_by_opt(const char *opt)
+{
+ key_t *key = NULL;
+ unsigned int i;
+
+ /* Sequential search. This is not a performance concern since the number
+ * of keys is bounded and the code runs on a host machine */
+ for (i = 0; i < num_keys; i++) {
+ key = &keys[i];
+ if (0 == strcmp(key->opt, opt)) {
+ return key;
+ }
+ }
+
+ return NULL;
+}
#include <openssl/x509v3.h>
#include "cert.h"
+#include "cmd_opt.h"
#include "debug.h"
#include "ext.h"
#include "key.h"
#endif /* OPENSSL_NO_EC */
};
-/* Command line options */
-static const struct option long_opt[] = {
- /* Binary images */
- {"bl2", required_argument, 0, BL2_ID},
- {"bl30", required_argument, 0, BL30_ID},
- {"bl31", required_argument, 0, BL31_ID},
- {"bl32", required_argument, 0, BL32_ID},
- {"bl33", required_argument, 0, BL33_ID},
- /* Certificate files */
- {"bl2-cert", required_argument, 0, BL2_CERT_ID},
- {"trusted-key-cert", required_argument, 0, TRUSTED_KEY_CERT_ID},
- {"bl30-key-cert", required_argument, 0, BL30_KEY_CERT_ID},
- {"bl30-cert", required_argument, 0, BL30_CERT_ID},
- {"bl31-key-cert", required_argument, 0, BL31_KEY_CERT_ID},
- {"bl31-cert", required_argument, 0, BL31_CERT_ID},
- {"bl32-key-cert", required_argument, 0, BL32_KEY_CERT_ID},
- {"bl32-cert", required_argument, 0, BL32_CERT_ID},
- {"bl33-key-cert", required_argument, 0, BL33_KEY_CERT_ID},
- {"bl33-cert", required_argument, 0, BL33_CERT_ID},
- /* Private key files */
- {"rot-key", required_argument, 0, ROT_KEY_ID},
- {"trusted-world-key", required_argument, 0, TRUSTED_WORLD_KEY_ID},
- {"non-trusted-world-key", required_argument, 0, NON_TRUSTED_WORLD_KEY_ID},
- {"bl30-key", required_argument, 0, BL30_KEY_ID},
- {"bl31-key", required_argument, 0, BL31_KEY_ID},
- {"bl32-key", required_argument, 0, BL32_KEY_ID},
- {"bl33-key", required_argument, 0, BL33_KEY_ID},
- /* Common options */
- {"key-alg", required_argument, 0, 'a'},
- {"help", no_argument, 0, 'h'},
- {"save-keys", no_argument, 0, 'k'},
- {"new-chain", no_argument, 0, 'n'},
- {"print-cert", no_argument, 0, 'p'},
- {0, 0, 0, 0}
-};
-
-static void print_help(const char *cmd)
+static void print_help(const char *cmd, const struct option *long_opt)
{
int i = 0;
printf("\n\n");
STACK_OF(X509_EXTENSION) * sk = NULL;
X509_EXTENSION *cert_ext = NULL;
ext_t *ext = NULL;
- cert_t *cert;
+ key_t *key = NULL;
+ cert_t *cert = NULL;
FILE *file = NULL;
int i, j, ext_nid;
int c, opt_idx = 0;
+ const struct option *cmd_opt;
+ const char *cur_opt;
unsigned int err_code;
unsigned char md[SHA256_DIGEST_LENGTH];
const EVP_MD *md_info;
/* Set default options */
key_alg = KEY_ALG_RSA;
+ /* Add common command line options */
+ cmd_opt_add("key-alg", required_argument, 'a');
+ cmd_opt_add("help", no_argument, 'h');
+ cmd_opt_add("save-keys", no_argument, 'k');
+ cmd_opt_add("new-chain", no_argument, 'n');
+ cmd_opt_add("print-cert", no_argument, 'p');
+
+ /* Initialize the certificates */
+ if (cert_init() != 0) {
+ ERROR("Cannot initialize certificates\n");
+ exit(1);
+ }
+
+ /* Initialize the keys */
+ if (key_init() != 0) {
+ ERROR("Cannot initialize keys\n");
+ exit(1);
+ }
+
+ /* Initialize the new types and register OIDs for the extensions */
+ if (ext_init() != 0) {
+ ERROR("Cannot initialize TBB extensions\n");
+ exit(1);
+ }
+
+ /* Get the command line options populated during the initialization */
+ cmd_opt = cmd_opt_get_array();
+
while (1) {
/* getopt_long stores the option index here. */
- c = getopt_long(argc, argv, "ahknp", long_opt, &opt_idx);
+ c = getopt_long(argc, argv, "ahknp", cmd_opt, &opt_idx);
/* Detect the end of the options. */
if (c == -1) {
}
break;
case 'h':
- print_help(argv[0]);
+ print_help(argv[0], cmd_opt);
break;
case 'k':
save_keys = 1;
case 'p':
print_cert = 1;
break;
- case BL2_ID:
- extensions[BL2_HASH_EXT].data.fn = strdup(optarg);
- break;
- case BL30_ID:
- extensions[BL30_HASH_EXT].data.fn = strdup(optarg);
- break;
- case BL31_ID:
- extensions[BL31_HASH_EXT].data.fn = strdup(optarg);
- break;
- case BL32_ID:
- extensions[BL32_HASH_EXT].data.fn = strdup(optarg);
- break;
- case BL33_ID:
- extensions[BL33_HASH_EXT].data.fn = strdup(optarg);
+ case CMD_OPT_EXT:
+ cur_opt = cmd_opt_get_name(opt_idx);
+ ext = ext_get_by_opt(cur_opt);
+ ext->data.fn = strdup(optarg);
break;
- case BL2_CERT_ID:
- certs[BL2_CERT].fn = strdup(optarg);
+ case CMD_OPT_KEY:
+ cur_opt = cmd_opt_get_name(opt_idx);
+ key = key_get_by_opt(cur_opt);
+ key->fn = strdup(optarg);
break;
- case TRUSTED_KEY_CERT_ID:
- certs[TRUSTED_KEY_CERT].fn = strdup(optarg);
- break;
- case BL30_KEY_CERT_ID:
- certs[BL30_KEY_CERT].fn = strdup(optarg);
- break;
- case BL30_CERT_ID:
- certs[BL30_CERT].fn = strdup(optarg);
- break;
- case BL31_KEY_CERT_ID:
- certs[BL31_KEY_CERT].fn = strdup(optarg);
- break;
- case BL31_CERT_ID:
- certs[BL31_CERT].fn = strdup(optarg);
- break;
- case BL32_KEY_CERT_ID:
- certs[BL32_KEY_CERT].fn = strdup(optarg);
- break;
- case BL32_CERT_ID:
- certs[BL32_CERT].fn = strdup(optarg);
- break;
- case BL33_KEY_CERT_ID:
- certs[BL33_KEY_CERT].fn = strdup(optarg);
- break;
- case BL33_CERT_ID:
- certs[BL33_CERT].fn = strdup(optarg);
- break;
- case ROT_KEY_ID:
- keys[ROT_KEY].fn = strdup(optarg);
- break;
- case TRUSTED_WORLD_KEY_ID:
- keys[TRUSTED_WORLD_KEY].fn = strdup(optarg);
- break;
- case NON_TRUSTED_WORLD_KEY_ID:
- keys[NON_TRUSTED_WORLD_KEY].fn = strdup(optarg);
- break;
- case BL30_KEY_ID:
- keys[BL30_KEY].fn = strdup(optarg);
- break;
- case BL31_KEY_ID:
- keys[BL31_KEY].fn = strdup(optarg);
- break;
- case BL32_KEY_ID:
- keys[BL32_KEY].fn = strdup(optarg);
- break;
- case BL33_KEY_ID:
- keys[BL33_KEY].fn = strdup(optarg);
+ case CMD_OPT_CERT:
+ cur_opt = cmd_opt_get_name(opt_idx);
+ cert = cert_get_by_opt(cur_opt);
+ cert->fn = strdup(optarg);
break;
case '?':
default:
/* Check command line arguments */
check_cmd_params();
- /* Register the new types and OIDs for the extensions */
- if (ext_register(extensions) != 0) {
- ERROR("Cannot register TBB extensions\n");
- exit(1);
- }
-
/* Indicate SHA256 as image hash algorithm in the certificate
* extension */
md_info = EVP_sha256();
static cert_t tbb_certs[] = {
[BL2_CERT] = {
.id = BL2_CERT,
+ .opt = "bl2-cert",
.fn = NULL,
.cn = "BL2 Certificate",
.key = ROT_KEY,
},
[TRUSTED_KEY_CERT] = {
.id = TRUSTED_KEY_CERT,
+ .opt = "trusted-key-cert",
.fn = NULL,
.cn = "Trusted Key Certificate",
.key = ROT_KEY,
},
[BL30_KEY_CERT] = {
.id = BL30_KEY_CERT,
+ .opt = "bl30-key-cert",
.fn = NULL,
.cn = "BL3-0 Key Certificate",
.key = TRUSTED_WORLD_KEY,
},
[BL30_CERT] = {
.id = BL30_CERT,
+ .opt = "bl30-cert",
.fn = NULL,
.cn = "BL3-0 Content Certificate",
.key = BL30_KEY,
},
[BL31_KEY_CERT] = {
.id = BL31_KEY_CERT,
+ .opt = "bl31-key-cert",
.fn = NULL,
.cn = "BL3-1 Key Certificate",
.key = TRUSTED_WORLD_KEY,
},
[BL31_CERT] = {
.id = BL31_CERT,
+ .opt = "bl31-cert",
.fn = NULL,
.cn = "BL3-1 Content Certificate",
.key = BL31_KEY,
},
[BL32_KEY_CERT] = {
.id = BL32_KEY_CERT,
+ .opt = "bl32-key-cert",
.fn = NULL,
.cn = "BL3-2 Key Certificate",
.key = TRUSTED_WORLD_KEY,
},
[BL32_CERT] = {
.id = BL32_CERT,
+ .opt = "bl32-cert",
.fn = NULL,
.cn = "BL3-2 Content Certificate",
.key = BL32_KEY,
},
[BL33_KEY_CERT] = {
.id = BL33_KEY_CERT,
+ .opt = "bl33-key-cert",
.fn = NULL,
.cn = "BL3-3 Key Certificate",
.key = NON_TRUSTED_WORLD_KEY,
},
[BL33_CERT] = {
.id = BL33_CERT,
+ .opt = "bl33-cert",
.fn = NULL,
.cn = "BL3-3 Content Certificate",
.key = BL33_KEY,
},
[BL2_HASH_EXT] = {
.oid = BL2_HASH_OID,
+ .opt = "bl2",
.sn = "TrustedBootFirmwareHash",
.ln = "Trusted Boot Firmware (BL2) hash (SHA256)",
.asn1_type = V_ASN1_OCTET_STRING,
},
[BL30_HASH_EXT] = {
.oid = BL30_HASH_OID,
+ .opt = "bl30",
.sn = "SCPFirmwareHash",
.ln = "SCP Firmware (BL30) hash (SHA256)",
.asn1_type = V_ASN1_OCTET_STRING,
},
[BL31_HASH_EXT] = {
.oid = BL31_HASH_OID,
+ .opt = "bl31",
.sn = "SoCAPFirmwareHash",
.ln = "SoC AP Firmware (BL31) hash (SHA256)",
.asn1_type = V_ASN1_OCTET_STRING,
},
[BL32_HASH_EXT] = {
.oid = BL32_HASH_OID,
+ .opt = "bl32",
.sn = "TrustedOSHash",
.ln = "Trusted OS (BL32) hash (SHA256)",
.asn1_type = V_ASN1_OCTET_STRING,
},
[BL33_HASH_EXT] = {
.oid = BL33_HASH_OID,
+ .opt = "bl33",
.sn = "NonTrustedWorldBootloaderHash",
.ln = "Non-Trusted World (BL33) hash (SHA256)",
.asn1_type = V_ASN1_OCTET_STRING,
static key_t tbb_keys[] = {
[ROT_KEY] = {
.id = ROT_KEY,
+ .opt = "rot-key",
.desc = "Root Of Trust key"
},
[TRUSTED_WORLD_KEY] = {
.id = TRUSTED_WORLD_KEY,
+ .opt = "trusted-world-key",
.desc = "Trusted World key"
},
[NON_TRUSTED_WORLD_KEY] = {
.id = NON_TRUSTED_WORLD_KEY,
+ .opt = "non-trusted-world-key",
.desc = "Non Trusted World key"
},
[BL30_KEY] = {
.id = BL30_KEY,
+ .opt = "bl30-key",
.desc = "BL30 key"
},
[BL31_KEY] = {
.id = BL31_KEY,
+ .opt = "bl31-key",
.desc = "BL31 key"
},
[BL32_KEY] = {
.id = BL32_KEY,
+ .opt = "bl32-key",
.desc = "BL32 key"
},
[BL33_KEY] = {
.id = BL33_KEY,
+ .opt = "bl33-key",
.desc = "BL33 key"
}
};